import threadpool,threading
from crawler_core.cache.search_cache import SearchCache
from crawler_core.constant.constants import Constants
from crawler_core.constant.constants_account import ConstantAccount
from crawler_core.constant.constants_api import ConstantAPI
from crawler_core.proxy.search_proxy import SearchProxy
from crawler_core.utils.redis_utils import RedisUtils
from lib.sys.logger_factory import LoggerFactory
from search_verify_code_server.impl.verify_51job import VerifyJob51

class TaskSearch(object):
    logger = LoggerFactory.getLogger("TaskSearch", "search")

    def __init__(self):
        pass

    def start(self):
        # 执行搜索任务
        def th(id):
            if id %2 ==0:
                task_id = RedisUtils.getSearchTask()
            else:
                task_id = RedisUtils.getSearchTaskRight()
            # 获取查询任务
            if not task_id:
                return
            TaskSearch.logger.info('搜索任务,获取任务ID -- [%s] --' % task_id)
            context = RedisUtils.getEventTask(task_id)
            if not context:
                return
            TaskSearch.logger.info('搜索任务 -- [%s] --,获取任务内容 ...' % task_id)

            _type = context[Constants.CONTEXT_TYPE]
            corp_code = context[Constants.CONTEXT_CORP_CODE]
            username = context[Constants.CONTEXT_USERNAME]
            # 获取cookie
            cookies = RedisUtils.getCookies(_type, corp_code, username)

            # 如果redis 里有该账号对应的cookie
            if cookies:
                # 开始执行任务
                TaskSearch.logger.info("搜索任务,  -- [%s] -- 执行查询， 获取 Cookies，开始执行查询..." % task_id)
                data = SearchProxy().search(context, cookies)
                code = data[Constants.SEARCH_CODE]
                # 1、解除登录锁定 (cookie失效)
                if code == ConstantAPI.RETURN_ERROR_COOKIES:
                    RedisUtils.addEventAccount(corp_code, _type, username, ConstantAccount.STATUS_COOKIES_LOSE)
                    TaskSearch.logger.info("搜索任务,  -- [%s] -- 执行查询， 任务失败--Cookies失效，重新登录 ..." % task_id)
                    # 再次将任务放置道队列中
                    RedisUtils.setLoginTask(task_id)

                # 发生未知异常
                elif code == ConstantAPI.RETURN_ERROR_UNKNOWN:
                    TaskSearch.logger.info("搜索任务,  -- [%s] -- 执行查询， 未知异常， 任务结束 ..." % task_id)
                    json_data = RedisUtils.getEventTask(task_id)
                    root_task_id = json_data[Constants.CONTEXT_ROOT_TASK_ID]
                    # @TODO 异常错误 需要回收 --记录主任务 channelType, account 加锁, 阻止 查询主任务 再次分配
                    # 删除当前任务
                    RedisUtils.delEventTask(task_id)
                    # 更新主任务状态 is_over = 1 任务完成
                    root_context = RedisUtils.getEventSearchContext(root_task_id)
                    root_context[Constants.CONTEXT_IS_OVER] = 1
                    RedisUtils.setEventSearchContext(root_task_id, root_context)

                # 中途出现验证码
                elif code == ConstantAPI.RETURN_ERROR_VERIFY:
                    TaskSearch.logger.info("搜索任务,  -- [%s] -- 执行查询， 中途出现验证码， 正在处理中 ..." % task_id)
                    url = data[Constants.CACHE_SEARCH_DATA]
                    VerifyJob51().verify(url,cookies)
                    TaskSearch.logger.info("搜索任务,  -- [%s] -- 执行查询， 中途出现的验证码,  已经处理好 ..." % task_id)

                else:
                    # 搜索成功
                    TaskSearch.logger.info("搜索任务,  -- [%s] -- 执行查询，搜索成功..." % task_id)
                    TaskSearch.logger.info("搜索任务,  -- [%s] -- 执行查询，发送搜索数据到缓冲池，解析数据 ..." % task_id)
                    # SearchCache.add(task_id, _type, data[Constants.CACHE_SEARCH_DATA])
                    SearchCache.add(task_id, _type, data)
            else:
                # 如果redis 里没有该账号对应的cookie
                TaskSearch.logger.info("搜索任务,  -- [%s] -- 执行查询，cookies不存在，重新登录 ..." % task_id)
                RedisUtils.setLoginTask(task_id)
        # 线程池方法
        # pool = threadpool.ThreadPool(4)
        # tasks = threadpool.makeRequests(th, range(1,3))
        # [pool.putRequest(task) for task in tasks]
        # pool.wait()
        for i in range(2):
            t = threading.Thread(target=th,args = (i,))
            t.start()
            t.join()